package com.ruyuan.user.server.controller.converter;

import com.ruyuan.gateway.sdk.facade.RuyuanGatewayFacade;
import com.ruyuan.user.api.model.enums.UserJobRelationTypeEnum;
import com.ruyuan.user.server.controller.request.SaveJobRequest;
import com.ruyuan.user.server.controller.response.JobListVO;
import com.ruyuan.user.server.controller.response.MultiJobListVO;
import com.ruyuan.user.server.domain.model.Job;
import com.ruyuan.user.server.domain.model.Organization;
import com.ruyuan.user.server.domain.service.JobDomainService;
import com.ruyuan.user.server.domain.service.OrganizationDomainService;
import com.ruyuan.user.server.util.OrganizationUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author xx
 */
@Component
public class WebJobConverter {

    @Autowired
    private RuyuanGatewayFacade ruyuanGatewayFacade;

    @Autowired
    private OrganizationDomainService organizationDomainService;

    @Autowired
    private JobDomainService jobDomainService;

    public Job convertSaveJobRequestToJob(SaveJobRequest request) {
        Job job = new Job();
        job.setId(request.getJobId());
        job.setSuperiorJobId(request.getSuperiorJobId());
        job.setOrgId(request.getOrgId());
        job.setIsBoss(request.getIsBoss());
        job.setName(request.getName());
        job.setDescription(request.getDescription());
        Long operator = ruyuanGatewayFacade.getCurrentUser().getUserId();
        job.setModifier(String.valueOf(operator));
        return job;
    }

    public List<JobListVO> convertToJobListVO(List<Job> jobList) {
        //缓存列表中所有的上级岗位信息
        Map<Long, Job> superiorJobMap = getSuperiorJobMap(jobList);
        //缓存列表中的部门信息
        Map<Long, Organization> orgMap = getOrgMap(jobList);
        return jobList.stream().map(job -> convertToJobListVO(job, superiorJobMap, orgMap)).collect(Collectors.toList());
    }

    public List<MultiJobListVO> convertToMultiJobListVO(Map<UserJobRelationTypeEnum, List<Job>> jobMap) {
        List<MultiJobListVO> res = new ArrayList<>();
        for (Map.Entry<UserJobRelationTypeEnum, List<Job>> entry : jobMap.entrySet()) {
            List<JobListVO> jobListVOS = convertToJobListVO(entry.getValue());
            for (JobListVO jobListVO : jobListVOS) {
                MultiJobListVO multiJobListVO = new MultiJobListVO();
                BeanUtils.copyProperties(jobListVO, multiJobListVO);
                multiJobListVO.setRelationType(entry.getKey().getCode());
                res.add(multiJobListVO);
            }
        }
        return res;
    }

    public JobListVO convertToJobListVO(Job job, Map<Long, Job> superiorJobMap, Map<Long, Organization> orgMap) {
        JobListVO jobListVO = new JobListVO();
        BeanUtils.copyProperties(job, jobListVO);
        if (job.getSuperiorJobId() != null && job.getSuperiorJobId() > 0L) {
            Job superiorJob = superiorJobMap.get(job.getSuperiorJobId());
            jobListVO.setSuperiorJobId(superiorJob.getId());
            jobListVO.setSuperiorJobName(superiorJob.getName());
            jobListVO.setSuperiorOrgId(superiorJob.getOrgId());
        }
        if (job.getOrgId() != null && job.getOrgId() > 0L) {
            jobListVO.setOrgNamePath(OrganizationUtil.buildOrgPathDisplayText(orgMap.get(job.getOrgId()), orgMap));
        }
        jobListVO.setJobId(job.getId());
        return jobListVO;
    }

    private Map<Long, Organization> getOrgMap(List<Job> jobList) {
        Map<Long, Organization> orgMap = new HashMap<>();
        jobList.stream().map(Job::getOrgId).distinct().forEach(
                orgId -> {
                    Organization organization = organizationDomainService.queryOrganizationById(orgId);
                    if (organization != null) {
                        orgMap.put(orgId, organization);
                    }
                }
        );
        //缓存组织全路径上的组织节点
        Map<Long, Organization> tempMap = new HashMap<>();
        orgMap.values().stream().map(Organization::getOrgPath).filter(CollectionUtils::isNotEmpty)
                .flatMap(Collection::stream).filter(orgId -> !orgMap.containsKey(orgId))
                .distinct().forEach(
                        orgId -> {
                            Organization organization = organizationDomainService.queryOrganizationById(orgId);
                            if (organization != null) {
                                tempMap.put(orgId, organization);
                            }
                        }
                );
        orgMap.putAll(tempMap);
        return orgMap;
    }

    private Map<Long, Job> getSuperiorJobMap(List<Job> jobList) {
        Map<Long, Job> superiorJobMap = new HashMap<>();
        jobList.forEach(job -> superiorJobMap.put(job.getId(), job));
        //跨部门的上级岗位处理，本部门的上级岗位可以直接从jobList中获取
        jobList.stream().map(Job::getSuperiorJobId).distinct()
                .filter(superiorJobId -> !superiorJobMap.containsKey(superiorJobId))
                .forEach(superiorJobId -> {
                    Job superiorJob = jobDomainService.queryById(superiorJobId);
                    if (superiorJob != null) {
                        superiorJobMap.put(superiorJobId, superiorJob);
                    }
                });
        return superiorJobMap;
    }

}
